package org.myh.excel.uitl;


import com.smart.common.util.myh.excel.uitl.strategy.DefaultTypeConvert;
import com.smart.common.util.myh.excel.uitl.strategy.TypeConvert;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * ClassName: ClassUtil
 * Description:
 * date: 2024/3/25 9:54
 *
 * @author Yu Han
 * @since JDK 1.8
 */
public final class ClassUtil<T> {

    private ConcurrentHashMap<String, Method> methodMap = new ConcurrentHashMap<>(256);
    private TypeConvert convert = new DefaultTypeConvert();

    public ClassUtil() {

    }

    /**
     * 获取一个新对象
     * @param clazz
     * @return
     */
    public T newInstance(Class clazz) {
        try {
            return (T) clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 给对象动态设置属性值
     * @param t
     * @param kv
     * @throws NullPointerException
     * @throws NoSuchFieldException
     */
    public void setFieldsByNames(T t, Map<String, String> kv) throws NullPointerException, NoSuchFieldException {
        if (kv == null || kv.size() <= 0) {
            throw new NullPointerException("传入属性K,V不存在");
        }
        Class<?> aClass = t.getClass();
        for (String key : kv.keySet()) {
            Field declaredField = aClass.getDeclaredField(key);
            declaredField.setAccessible(true);
            try {
                declaredField.set(t, kv.get(key));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 为对象赋值
     * @param t 传入要赋值的对象
     * @param typeName 类型名
     * @param typeValue 类型值
     * @throws NoSuchFieldException
     */
    public void setFieldByName(T t,String typeName,String typeValue) throws NoSuchFieldException, IllegalAccessException {
        Class<?> aClass = t.getClass();
        Field declaredField = aClass.getDeclaredField(typeName);
        declaredField.setAccessible(true);
        declaredField.set(t,convert.getConvertValue(declaredField.getType().getTypeName(),typeValue));
    }

    /**
     * 根据方法名执行方法
     * @param t 需要执行操作的对象
     * @param methodName 方法名
     * @return
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public T invoke(T t, String methodName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method method = null;
        String UpperCaseMethodName = methodName.toUpperCase();
        Class<?> aClass = t.getClass();
        if (methodMap.size() == 0) {
            methodMap.put(UpperCaseMethodName, method = aClass.getMethod(methodName));
            method.setAccessible(true);
        } else {
            method = methodMap.get(UpperCaseMethodName);
            if (method == null) {
                methodMap.put(UpperCaseMethodName, method = aClass.getMethod(methodName));
            }
            method.setAccessible(true);
        }
        return (T)method.invoke(t);
    }

}
